import math
import time
import requests
from concurrent.futures import ThreadPoolExecutor, as_completed
from datetime import datetime

# 全局配置
COOKIES = {
    'JSESSIONID': '49906DF6AAFFF1A9069DD321E7929174',
    'tempTokenKey': 'eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiLnhormr4UiLCJhdWQiOiI5RTEwNTlDOTMzNUQ0QzdDQjhEQzc0MDBEMDNBRUNGQiIsInNlcnZlciI6Imh0dHA6Ly81OS4yMTUuMjA2LjE4OC9sb2dpbi8iLCJyb2xlIjoiUk9MRV9BUkVBLFJPTEVfV0lORE9XIiwiaXNJbml0aWFsUGFzc3dvcmQiOiIwIiwicmVnaW9uTmFtZSI6Iui0teW3nuecgSIsImluZHVzdHJ5IjpudWxsLCJhcHBDb2RlIjoiZGdvdi1wb3JnYWwiLCJvcmdhbk5hbWUiOiLmlrDov5vkurrlkZgiLCJyZWdpb25Db2RlIjoiNTIwMDAwIiwiaW5kdXN0cnlMaXN0IjpudWxsLCJvcmdhbkNvZGUiOiI1MjAwMDAyMDE3MDIxNjEwMDUzMDAwMDUwNyIsImV4cGlyYXRpb25UaW1lIjo0LCJncmFkZSI6IjIiLCJzdGF0dXMiOiIxIiwiaXNzIjoiaW5zcHVyIiwiaWF0IjoxNzU0MDA5ODIwLCJleHAiOjE3NTQwMzg2MjB9.Ou9_bG0RpVsjZB2R7GGNURY-V4LgXdr6ovPfUdoDV6WFZZGKxu2c02jWCC4uZnW9_w-vFdffClv5OgMc0j8QpA',
    'userInfoKey': '{%22role%22:%22ROLE_AREA%2CROLE_WINDOW%22%2C%22isInitialPassword%22:%220%22%2C%22regionName%22:%22%E8%B4%B5%E5%B7%9E%E7%9C%81%22%2C%22appCode%22:%22dgov-portal%22%2C%22organName%22:%22%E6%96%B0%E8%BF%9B%E4%BA%BA%E5%91%98%22%2C%22regionCode%22:%22520000%22%2C%22phone%22:%22384d53fa06a4844cfd54260b048c33e9%22%2C%22organCode%22:%2252000020170216100530000507%22%2C%22expirationTime%22:4%2C%22name%22:%221342b48e6f8f39ea7ba36accc05b61a8%22%2C%22id%22:%229E1059C9335D4C7CB8DC7400D03AECFB%22%2C%22email%22:%223f9980534589201ab2c5f2481db36392%22%2C%22username%22:%2247d57692a252657367001b6a2ff35333%22%2C%22status%22:%221%22%2C%22isWeakPwd%22:%220%22}',
    'pwdState': 'true',
    'inspurRoleKey': 'ROLE_AREA',
    'windowId': '0B7CA12E92004E0ABCA9EB88F0A792E4',
    'James_cookie_sYQDUGqqzHtheme': 'custom',
    'webfinal.session.errorCount': '0',
    'tempTokenKey-slsp': 'eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiLnhormr4UiLCJhdWQiOiI5RTEwNTlDOTMzNUQ0QzdDQjhEQzc0MDBEMDNBRUNGQiIsInNlcnZlciI6Imh0dHA6Ly81OS4yMTUuMjA2LjE4OC9oYW5kbGUtYnVzaW5lc3MtdWkvIiwicm9sZSI6IkNKWVlfU1lTVEVNLENKWVlfQlVTSU5FU1NfREVsRVRFLENKWVlfQlVTSU5FU1NfREVsRVRFX0VYQU1JTkUsQ0pZWV9CVVNJTkVTUyIsImlzSW5pdGlhbFBhc3N3b3JkIjoiMCIsInJlZ2lvbk5hbWUiOiLotLXlt57nnIEiLCJpbmR1c3RyeSI6bnVsbCwiYXBwQ29kZSI6IkRHT1YtWldGVy1TTFNQIiwib3JnYW5OYW1lIjoi5paw6L-b5Lq65ZGYIiwicmVnaW9uQ29kZSI6IjUyMDAwMCIsImluZHVzdHJ5TGlzdCI6bnVsbCwib3JnYW5Db2RlIjoiNTIwMDAwMjAxNzAyMTYxMDA1MzAwMDA1MDciLCJleHBpcmF0aW9uVGltZSI6NCwiZ3JhZGUiOiIyIiwic3RhdHVzIjoiMSIsImlzcyI6Imluc3B1ciIsImlhdCI6MTc1NDAxMzkyOCwiZXhwIjoxNzU0MDQyNzI4fQ.Y6c2VdXbmkMcaN8h6x06L_fhWDO30JefBMUP3n5IpV3Nvw0ycL_GvXihMv_NDtehJknYGO5kDORBcsjUHgcGUg',
    'userInfoKey-slsp': '{%22role%22:%22CJYY_SYSTEM%2CCJYY_BUSINESS_DElETE%2CCJYY_BUSINESS_DElETE_EXAMINE%2CCJYY_BUSINESS%22%2C%22isInitialPassword%22:%220%22%2C%22regionName%22:%22%E8%B4%B5%E5%B7%9E%E7%9C%81%22%2C%22appCode%22:%22DGOV-ZWFW-SLSP%22%2C%22organName%22:%22%E6%96%B0%E8%BF%9B%E4%BA%BA%E5%91%98%22%2C%22regionCode%22:%22520000%22%2C%22phone%22:%2218198171062%22%2C%22organCode%22:%2252000020170216100530000507%22%2C%22expirationTime%22:4%2C%22name%22:%22%E7%86%8A%E6%AF%85%22%2C%22id%22:%229E1059C9335D4C7CB8DC7400D03AECFB%22%2C%22email%22:%22123@qq.com%22%2C%22username%22:%22gys_xy%22%2C%22status%22:%221%22%2C%22windowId%22:%2211EF7D785488E5FCBAD4AF91FADA434E%22%2C%22windowName%22:%22%E9%81%B5%E4%B9%89%E5%B8%82%E4%B8%80%E4%BB%B6%E4%BA%8B%E7%AA%97%E5%8F%A3%22%2C%22windowCode%22:%22%E9%81%B5%E4%B9%89%E5%B8%82%E4%B8%80%E4%BB%B6%E4%BA%8B%E7%AA%97%E5%8F%A3%22%2C%22hallName%22:%22%E9%81%B5%E4%B9%89%E5%B8%82%E6%94%BF%E5%8A%A1%E6%9C%8D%E5%8A%A1%E4%B8%AD%E5%BF%83%22%2C%22hallCode%22:%2200001%22%2C%22windowRegionCode%22:%22520300%22%2C%22signAuthCode%22:%2252030000017129%22}',
}

HEADERS = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:139.0) Gecko/20100101 Firefox/139.0',
    'Accept': 'application/json, text/javascript, */*; q=0.01',
    'Accept-Language': 'zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2',
    'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
    'X-Requested-With': 'XMLHttpRequest',
    'Origin': 'http://59.215.206.188',
    'Connection': 'keep-alive',
    'Referer': 'http://59.215.206.188/zhslzy/accept/worktodolist/todoFinishIndex',
    'Priority': 'u=0',
}

PARAMS = {'isAllDeal': ''}

BASE_DATA = {
    "signstate": "94,95,",
    "_search": "true",
    "nd": time.time() * 1000,
    "rows": "100",
    "sidx": "RECEIVE_TIME",
    "sord": "desc",
    "receivenum": "",
    "applicant": "",
    "itemname": "",
    "getbarcode": "",
    "submitTime": "2010-01-01+至+2023-12-31",
    "submitTime_start": "2010-01-01",
    "submitTime_end": "2025-12-31",
    "curState": "",
    "regionName": "赤水市天台镇,赤水市复兴镇,赤水市镇,赤水市石堡乡,赤水市丙安镇,赤水市元厚镇,赤水市大同镇,赤水市旺隆镇,赤水市宝源乡,赤水市镇,赤水市官渡镇,赤水市白云乡,赤水市葫市镇,赤水市金华街道,赤水市文华街道,赤水市两河口镇,赤水市市中街道,赤水市",
    "regionCode": "52038104,52038102,52038103,52038105,52038106,52038107,52038108,52038109,52038110,52038111,52038112,52038113,52038114,52038115,52038116,52038117,52038118,520381"
}

# 输出文件路径（包含时间戳避免覆盖）
OUTPUT_FILE = f"receive_numbers_{datetime.now().strftime('%Y%m%d_%H%M%S')}.txt"


def fetch_page(page_num):
    """查询指定页码并返回RECEIVE_NUMBER列表"""
    try:
        page_data = BASE_DATA.copy()
        page_data['page'] = str(page_num)
        page_data['nd'] = time.time() * 1000  # 刷新时间戳

        response = requests.post(
            'http://59.215.206.188/zhslzy/accept/worktodolist/querytodofinish',
            params=PARAMS,
            cookies=COOKIES,
            headers=HEADERS,
            data=page_data,
            timeout=15
        )
        response.raise_for_status()
        json_data = response.json()

        # 验证返回数据格式
        if 'rows' not in json_data:
            raise ValueError(f"页码 {page_num} 返回数据格式错误")

        return [row['cell']['RECEIVE_NUMBER'] for row in json_data['rows']]

    except Exception as e:
        print(f"❌ 页码 {page_num} 查询失败: {str(e)}")
        return []


def save_to_file(numbers, filename):
    """将号码列表写入TXT文件"""
    try:
        with open(filename, 'a', encoding='utf-8') as f:  # 使用追加模式
            for num in numbers:
                f.write(f"{num}\n")
        return True
    except Exception as e:
        print(f"❌ 写入文件失败: {str(e)}")
        return False


def main():
    start_time = time.time()
    print(f"===== 开始查询任务 =====")
    print(f"开始时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
    print(f"结果将保存至: {OUTPUT_FILE}\n")

    # 1. 获取总页数
    total_pages = 0
    try:
        first_page_data = BASE_DATA.copy()
        first_page_data['page'] = '1'
        response = requests.post(
            'http://59.215.206.188/zhslzy/accept/worktodolist/querytodofinish',
            params=PARAMS,
            cookies=COOKIES,
            headers=HEADERS,
            data=first_page_data,

        )
        response.raise_for_status()
        json_data = response.json()

        total_records = int(json_data.get('records', 0))
        if total_records == 0:
            print("⚠️ 未查询到任何记录")
            return

        total_pages = math.ceil(total_records / 100)
        print(f"📊 共发现 {total_records} 条记录，分 {total_pages} 页")

    except Exception as e:
        print(f"❌ 获取总页数失败: {str(e)}")
        return

    # 2. 多线程查询所有页
    all_numbers = []
    max_workers = 5  # 并发线程数

    with ThreadPoolExecutor(max_workers=max_workers) as executor:
        future_to_page = {
            executor.submit(fetch_page, page): page
            for page in range(1, total_pages + 1)
        }

        for future in as_completed(future_to_page):
            page_num = future_to_page[future]
            try:
                page_numbers = future.result()
                all_numbers.extend(page_numbers)

                # 实时写入文件，避免内存占用过大
                if page_numbers:
                    save_to_file(page_numbers, OUTPUT_FILE)

                print(f"✅ 完成页码 {page_num}/{total_pages}，累计 {len(all_numbers)} 条")

            except Exception as e:
                print(f"❌ 处理页码 {page_num} 出错: {str(e)}")

    # 3. 完成统计
    end_time = time.time()
    elapsed = round(end_time - start_time, 2)

    print(f"\n===== 查询任务完成 =====")
    print(f"总耗时: {elapsed} 秒")
    print(f"共获取 {len(all_numbers)} 条RECEIVE_NUMBER")
    print(f"结果已保存至: {OUTPUT_FILE}")


if __name__ == "__main__":
    main()
